#include <cerrno>
#include <fstream>
#include <sys/types.h>
#include <sys/wait.h>
#include <iostream>
#include <unistd.h>
#include <cstring>
#include <string>
 
int main() {
    int a=1;
    pid_t cpid;
    int pipefd[2];
    
 
    // 创建管道

    //这是一个匿名管道
    // pipefd[0] 是读端
    // pipefd[1] 是写端
    if (pipe(pipefd) == -1) {
        // 创建管道失败
        perror("pipe");
        return EXIT_FAILURE;
    }
 
    // 复制父子进程
    //fork()用于创建一个子进程
    //他有两个返回值
    //在父进程返回子进程的pid
    //在子进程返回0
    //如果fork()失败返回-1
    //这样可以用于区分父子进程
    a++;
    cpid = fork();
    if (cpid == -1) {
        perror("fork");
        return EXIT_FAILURE;
    }
 
    
    if (cpid == 0) {
        // 子进程
        // 关闭写端
        close(pipefd[1]);
 
        std::string str = "子进程 " + std::to_string(getpid()) + " 接收到的信息：";
        write(STDOUT_FILENO, str.c_str(), str.length());
 
        char buffer[1024];
        // 读取父进程传递过来的信息(管道的数据) 打印到控制台
        while (read(pipefd[0], &buffer, 2) > 0) {
            // 读到数据
            write(STDOUT_FILENO, &buffer, 2);
        }
        write(STDOUT_FILENO, "\n", 1);
        a++;
        std::string str2="子进程打印a: "+std::to_string(a)+"\n";
        write(STDOUT_FILENO,str2.c_str(),str2.length());
        // 关闭读
        close(pipefd[0]);
 
        // exit 父进程 _exit 子进程 方便区分
        _exit(EXIT_SUCCESS);
    } else {
        // 父进程
        // 将父进程传递过来的信息写入管道 传递给子进程
        // 首先要关闭读
        close(pipefd[0]);
 
        // 刷新标准输出缓冲区
        std::fflush(stdout); 
 
        write(pipefd[1], "hello i'm your farther", strlen("hello i'm your farther"));
 
        std::string str="父进程打印a: "+std::to_string(a)+"\n";
        // 关闭写
        close(pipefd[1]);
 
        write(STDOUT_FILENO,str.c_str(),str.length());
        // 等待子进程结束
        waitpid(cpid, NULL, 0);
        return EXIT_SUCCESS;
    }
 
    return 0;
}
 